package com.study.bean;

import org.junit.Test;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.context.*;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.StringValueResolver;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

/**
 * Spring 中 Bean 的生命周期
 * 参考 https://blog.csdn.net/kykangyuky/article/details/123114227
 * 参考 https://www.cnblogs.com/zrtqsk/p/3735273.html
 *
 * @author doveylovey
 * @version v1.0.0
 * @email 1135782208@qq.com
 * @date 2020年12月08日
 */
public class BeanLifeTests01 {
    @Test
    public void testBeanLife() {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BeanLifeTests01Config.class);
        BeanLifeTest beanLifeTest = applicationContext.getBean("beanLifeTest", BeanLifeTest.class);
        System.out.println("获取 bean 的属性值：" + beanLifeTest.getParam());
        applicationContext.close();
    }
}

@Configuration
class BeanLifeTests01Config {
    @Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
    public BeanLifeTest beanLifeTest() {
        BeanLifeTest beanLifeTest = new BeanLifeTest();
        beanLifeTest.setParam("给 BeanLifeTest 类的 param 参数设置的值");
        return beanLifeTest;
    }
}

class BeanLifeTest implements BeanNameAware, BeanFactoryAware, ApplicationContextAware,
        InitializingBean, DisposableBean, BeanClassLoaderAware, EnvironmentAware,
        EmbeddedValueResolverAware, ResourceLoaderAware,
        ApplicationEventPublisherAware, MessageSourceAware, BeanPostProcessor, DestructionAwareBeanPostProcessor {
    private String param;

    public BeanLifeTest() {
        System.out.println("BeanLifeTest 类的无参构造方法");
    }

    public BeanLifeTest(String param) {
        System.out.println("BeanLifeTest 类的有参构造方法，param=" + param);
        this.param = param;
    }

    public String getParam() {
        return param;
    }

    public void setParam(String param) {
        System.out.println("BeanLifeTest 类的 param 属性的 setParam() 方法");
        this.param = param;
    }

    @PostConstruct
    public void postConstruct() {
        // 自定义初始化方法
        System.out.println("BeanLifeTest 类的 @PostConstruct 注解方法");
    }

    public void initMethod() {
        System.out.println("BeanLifeTest 类的 initMethod() 方法");
    }

    @PreDestroy
    public void preDestroy() {
        // 自定义销毁方法
        System.out.println("BeanLifeTest 类的 preDestroy() 方法");
    }

    public void destroyMethod() {
        System.out.println("BeanLifeTest 类的 destroyMethod() 方法");
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("BeanLifeTest 类的 finalize() 方法");
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("BeanLifeTest 类的 setBeanClassLoader() 方法");
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("BeanLifeTest 类的 setBeanFactory() 方法");
    }

    @Override
    public void setBeanName(String name) {
        System.out.println("BeanLifeTest 类的 setBeanName() 方法");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("BeanLifeTest 类的 destroy() 方法");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("BeanLifeTest 类的 afterPropertiesSet() 方法");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("BeanLifeTest 类的 setApplicationContext() 方法");
    }

    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        System.out.println("BeanLifeTest 类的 setApplicationEventPublisher() 方法");
    }

    @Override
    public void setEmbeddedValueResolver(StringValueResolver resolver) {
        System.out.println("BeanLifeTest 类的 setEmbeddedValueResolver() 方法");
    }

    @Override
    public void setEnvironment(Environment environment) {
        System.out.println("BeanLifeTest 类的 setEnvironment() 方法");
    }

    @Override
    public void setMessageSource(MessageSource messageSource) {
        System.out.println("BeanLifeTest 类的 setMessageSource() 方法");
    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        System.out.println("BeanLifeTest 类的 setResourceLoader() 方法");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof BeanLifeTest) {
            // 容器加载的时候会加载一些其他的 bean，会调用初始化前和初始化后方法
            System.out.println("BeanLifeTest 类的 postProcessBeforeInitialization() 方法");
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean instanceof BeanLifeTest) {
            // 容器加载的时候会加载一些其他的 bean，会调用初始化前和初始化后方法
            System.out.println("BeanLifeTest 类的 postProcessAfterInitialization() 方法");
        }
        return bean;
    }

    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        System.out.println("BeanLifeTest 类的 postProcessBeforeDestruction() 方法");
    }

    @Override
    public boolean requiresDestruction(Object bean) {
        System.out.println("BeanLifeTest 类的 requiresDestruction() 方法");
        return true;
    }
}